package com.my.study.structures.linkedlist;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Carlos
 * @version 1.0
 * @Description 双向链表
 * @date 2021/6/10 22:39
 **/
@Slf4j(topic = "c.DoubleLinkedList")
public class DoubleLinkedList {

    /**
     * 头结点
     */
    private HeroNode head = new HeroNode(0, "", "");

    /**
     * 获取头结点
     * @return
     */
    public HeroNode getHead() {
        return this.head;
    }

    /**
     * 添加结点到尾部
     *
     * @param no
     * @param name
     * @param nickname
     */
    public void addLast(int no, String name, String nickname) {
        // 定义一个辅助节点，用于从头节点开始遍历整个列表
        HeroNode temp = head;
        while (true) {
            // 找到链表最后
            if (temp.next == null) {
                break;
            }
            // 如果没有找到，后移
            temp = temp.next;
        }
        HeroNode heroNode = new HeroNode(no, name, nickname);
        temp.next = heroNode;
        heroNode.pre = temp;
    }

    /**
     * 修改链表
     *
     * @param no
     * @param name
     * @param nickname
     */
    public void update(int no, String name, String nickname) {
        HeroNode temp, newNode;
        // 表示是否找到节点
        boolean flag = false;
        if ((temp = head.next) == null) {
            throw new RuntimeException("链表为空");
        }
        newNode = new HeroNode(no, name, nickname);
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.no == newNode.no) {
                flag = true;
                break;
            }

            temp = temp.next;
        }
        // 找到
        if (flag) {
            temp.name = newNode.name;
            temp.nickname = newNode.nickname;
        } else {
            log.debug("没有找到编号为[{}]的节点", newNode.no);
            throw new RuntimeException("没有找到满足条件的节点");
        }
    }

    /**
     * 删除链表
     *
     * @param no
     */
    public void delete(int no) {
        HeroNode temp;
        if ((temp = head.next) == null) {
            log.debug("链表为空，无法删除");
            return;
        }

        // 表示是否找到节点
        boolean flag = false;
        while (true) {
            if (temp == null) {
                break;
            }
            if (temp.no == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if (flag) {
            temp.pre.next = temp.next;
            // 这里有风险，万一是最后一个结点，就会出现空指针异常
            if (temp.next != null) {
                temp.next.pre = temp.pre;
            }
        } else {
            log.debug("要删除的节点[{}]不存在", no);
            throw new RuntimeException("要删除的节点不存在");
        }
    }


    /**
     * 遍历链表
     */
    public void list() {
        // 判断是否为空
        if (head.next == null) {
            return;
        }
        HeroNode temp = head.next;
        while (true) {
            if (temp == null) {
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }

    }


    static class HeroNode {
        private int no;
        private String name;
        private String nickname;
        // 指向下一个节点
        private HeroNode next;
        // 指向前一个节点
        private HeroNode pre;

        public HeroNode(int no, String name, String nickname) {
            this.no = no;
            this.name = name;
            this.nickname = nickname;
        }

        @Override
        public String toString() {
            return "HeroNode{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    ", nickname='" + nickname + '\'' +
                    '}';
        }


    }


}
